package com.ansion.commonchat.startup;

import android.graphics.Bitmap;
import android.os.Looper;
import android.util.Printer;

import androidx.annotation.WorkerThread;

import com.ansion.commonchat.BaseApplication;
import com.ansion.commonchat.contact.ContactsLoadManager;
import com.ansion.commonchat.contact.systemcontact.AndroidContactsFactory;
import com.ansion.commonchat.db.CocoDBFactory;
import com.ansion.commonchat.startup.fresco.fetcher.FrescoFetcherExtension;
import com.ansion.commonchat.startup.workmanager.bwork.BOneTimeWorkRequest;
import com.ansion.commonchat.startup.workmanager.bwork.BWorkManager;
import com.ansion.constant.BConstant;
import com.ansion.utils.ThreadUtil;
import com.ansion.log.VLog;
import com.ansion.preference.TurboBasePreference;
import com.ansion.utils.LogFileUtil;
import com.ansion.utils.ResourceUtils;
import com.ansion.xlog.XLogger;
import com.ansion.xlog.Xlog;
import com.facebook.cache.disk.DiskCacheConfig;
import com.facebook.common.util.ByteConstants;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.imagepipeline.core.ImagePipelineConfig;
import com.facebook.imagepipeline.nativecode.ImagePipelineNativeLoader;
import com.tencent.mmkv.MMKV;
import com.tencent.mmkv.MMKVLogLevel;

/****
 * @author john 2022/04/07
 * @desc 启动任务管理器，为不同配置的机型提供最佳任务路径
 */
public class AppStartTaskExecutor {

    public static void initEvn() {
        initBaseLib();
        initMMKV();
        initFresco();
        initDataBase();
        ThreadUtil.runOnWorker(()->{
//            CocoDBFactory.getInstance().syncPreloadData();
        });
    }
    /***
     * 初始化mmkv
     */
    public static void initMMKV() {
        VLog.OPEN_LOG = true;
        VLog.stopD("trackKey", "%s mmkv init start", "trackKey");
        try {
            String path = MMKV.initialize(ResourceUtils.getContext(), MMKVLogLevel.LevelNone);
            if (VLog.OPEN_LOG) {
                VLog.e("mmkv", "mmkv path: " + path);
            }
            TurboBasePreference.MMKVPath = path;
            TurboBasePreference.MMKVEnable = true;
        } catch (Throwable e) {
            TurboBasePreference.MMKVEnable = false;
        }
        TurboBasePreference.mmkvInited = true;
        VLog.stopD("trackKey", "%s mmkv init end", "trackKey");
    }
    /***
     * 初始化基础库
     */
    public static void initBaseLib() {
        //采用xlog写文件的实现，线上log文件
        String cacheDir = LogFileUtil.getLogFileCacheDir();
        String logDir = LogFileUtil.getLogFileDir();
        XLogger fileLogger = new XLogger(Xlog.AppednerModeAsync, cacheDir, 7, logDir, "log");
        VLog.init(fileLogger);
//        HttpSdkEnvHelper.init(new HttpRequestGetInjectServiceImpl());

        // debug ui thread
        if (VLog.OPEN_LOG) {
            Looper.getMainLooper().setMessageLogging(new Printer() {
                @Override
                public void println(String x) {
                    if (x.startsWith(">>>>> Dispatching")) {
//                        UIMonitor.getInstance().startMonitor();
//                        UIMonitor.getInstance().startAnrMonitor();
                    }
                    if (x.startsWith("<<<<< Finished")) {
//                        UIMonitor.getInstance().removeMonitor();
//                        UIMonitor.getInstance().removeAnrMonitor();
                    }
                }
            });
        }
    }
    /***
     * 初始化fresco
     */
    public static void initFresco() {
        DiskCacheConfig diskCacheConfig =
                DiskCacheConfig.newBuilder(ResourceUtils.getContext())
                        .setBaseDirectoryName("image_cache")
                        .setMaxCacheSize(1000 * ByteConstants.MB)
                        .setMaxCacheSizeOnLowDiskSpace(20 * ByteConstants.MB)
                        .build();

        // 小图片缓存设置
        DiskCacheConfig smallImageDiskCacheConfig =
                DiskCacheConfig.newBuilder(ResourceUtils.getContext())
                        .setBaseDirectoryPath(ResourceUtils.getContext().getExternalFilesDir(null))
                        .setMaxCacheSize(1000 * ByteConstants.MB)
                        .setMaxCacheSizeOnLowDiskSpace(20 * ByteConstants.MB)
                        .build();
        FrescoFetcherExtension frescoFetcherExtension = FrescoFetcherExtension.get();
        frescoFetcherExtension.register(new CustomFrescoFetcher());
//        frescoFetcherExtension.register(new PdfFetcher());

        ImagePipelineConfig.Builder builder =
                ImagePipelineConfig.newBuilder(ResourceUtils.getContext())
                        .setNetworkFetcher(frescoFetcherExtension)
                        .setDownsampleEnabled(true)
                        .setResizeAndRotateEnabledForNetwork(true)
                        .setBitmapsConfig(Bitmap.Config.RGB_565)
                        .setMainDiskCacheConfig(diskCacheConfig)
                        .setSmallImageDiskCacheConfig(smallImageDiskCacheConfig);
        Fresco.initialize(ResourceUtils.getContext(), builder.build());

        try {
            ImagePipelineNativeLoader.load();
        } catch (UnsatisfiedLinkError error) {
            Fresco.shutDown();
            builder.experiment().setNativeCodeDisabled(true);
//            ImagePipelineConfig.Builder builder1 = builder.experiment().setNativeCodeDisabled(true);
            Fresco.initialize(ResourceUtils.getContext(), builder.build());
        }
    }
    /***
     * 初始化用户数据库
     */
    public static void initDataBase() {
        String key = "APP_START";
        VLog.d(key, "%s initUserDataBase start:%d", key, 1234560);
        CocoDBFactory.getInstance().initDB(1234560);
        //todo 建表操作放到后面，讨论后再搞
//        SearchSdkFactory.getSdk().createSearchTable();
        VLog.stopD(key, "%s initUserDataBase end", key);
    }
    /***
     * 1、同步系统联系人到本地的User表
     * 2、同步系统联系人到server
     */
    @WorkerThread
    public static void syncContact() {
        //同步加载，避免在子线程再创建线程
        AndroidContactsFactory.getAllContacts();
        ContactsLoadManager.getInstance().loadLocalContacts();
    }

    public static void initDelaydTask() {
        ThreadUtil.getWorkerHandler().post(() -> {
            BOneTimeWorkRequest syncContactWorkRequest = new BOneTimeWorkRequest.Builder(SyncContactWorker.class)
                    .addTag(BConstant.AppStart.TAG_SYNC_CONTACT)
                    .build();
            BWorkManager.getInstance(BaseApplication.getContext())
                    .beginWith(syncContactWorkRequest)
                    .enqueue();
        });
    }
}
